package com.niuwa.p2p.core.finance;

import java.math.BigDecimal;

import com.niuwa.p2p.core.constant.Constants;

public class CostCalculatorHelper {

	
	/**
	 * 计算n天利息和--针对新客专享
	 * 还款日利率=月利率*12/360
	 * 公式: 日利率*天数*金额
	 * @param day
	 * @param amount
	 * @param yearRate 如：8
	 * @return
	 */
	public static BigDecimal dayInterest(Integer day,BigDecimal amount,BigDecimal yearRate){
		return amount.multiply(yearRate).multiply(new BigDecimal(day)).divide(new BigDecimal("36000"), 2, BigDecimal.ROUND_HALF_DOWN);
	}
	/**
	 * 等额本息  月还额度
	 * 
	 * @Description
	 * @param amount
	 * @param rate 如：18
	 * @param monthSum
	 * @return
	 * @author liuhuan
	 */
	public static BigDecimal monthlyAmount(BigDecimal amount, BigDecimal rate, BigDecimal monthSum) {
		// :每月月供额=〔贷款本金×月利率×(1＋月利率)＾还款月数〕÷〔(1＋月利率)＾还款月数-1〕
		BigDecimal monthApr = rate.divide(new BigDecimal("1200"), 20, BigDecimal.ROUND_HALF_UP);
		BigDecimal flag = new BigDecimal("1");
		// (1＋月利率)＾还款月数
		BigDecimal temp = (flag.add(monthApr)).pow(monthSum.intValue());
		BigDecimal first = amount.multiply(monthApr).multiply(temp);
		BigDecimal second = temp.subtract(flag);
		return first.divide(second, 2, BigDecimal.ROUND_HALF_UP);
	}
	
	/**
	 * 等额本息  月还利息
	 * 贷款本金*月利率*(1+月利率)^还贷总月数/[(1+月利率)^还贷总月数-1]-贷款本金*月利率(1+月利率)^(当前还款月-1)/[(1+
	 * 月利率)^还贷总月数-1] a*i(1+i)^N/[(1+i)^N-1]-a*i(1+i)^(n-1)/[(1+i)^N-1]
	 * @author liuhuan
	 */
	public static BigDecimal monthlyInterest(BigDecimal amount, BigDecimal rate, BigDecimal monthSum, BigDecimal thisMonth) {
		BigDecimal monthApr = rate.divide(new BigDecimal("1200"), 20, BigDecimal.ROUND_HALF_DOWN);
		BigDecimal flag = new BigDecimal("1");
		// (1+i)^N
		BigDecimal a = (monthApr.add(flag)).pow(monthSum.intValue()).setScale(20, BigDecimal.ROUND_HALF_DOWN);
		// (1+i)^(n-1)
		BigDecimal b = (monthApr.add(flag)).pow((thisMonth.intValue() - 1)).setScale(20, BigDecimal.ROUND_HALF_DOWN);
		// a*i(1+i)^N/[(1+i)^N-1]
		BigDecimal c = (amount.multiply(monthApr).multiply(a)).divide(a.subtract(flag), 20, BigDecimal.ROUND_HALF_DOWN);
		// a*i(1+i)^(n-1)/[(1+i)^N-1]
		BigDecimal d = (amount.multiply(monthApr).multiply(b)).divide(a.subtract(flag), 20, BigDecimal.ROUND_HALF_DOWN);
		return c.subtract(d).setScale(2, BigDecimal.ROUND_HALF_DOWN);
	}
	
	/**
     * 到期还本付息  总利息
     * 
     * @param amount
     * @param rate 如：18
     * @param monthSum
     */
    public static BigDecimal disposableInterest(BigDecimal amount, BigDecimal rate, BigDecimal monthSum) {
        BigDecimal monthApr = rate.divide(new BigDecimal("1200"), 20, BigDecimal.ROUND_HALF_DOWN);
        BigDecimal disposableInterest = amount.multiply(monthApr).multiply(monthSum).setScale(2, BigDecimal.ROUND_HALF_DOWN);
        return disposableInterest;
    }
	
	
	
	
	/*--------------P2P平台借款费率------------------------*/

	// 1）支付方：借款人
	// 基本 月利息=待收本金*月利率
	
	// 基本 平台服务费=提现金额*平台服务费率	
	/**
	 * 平台服务费计算
	 * 平台服务费 = 还款总额  * 平台服务费率
	 * 
	 * @param repayTotalAmout 还款总额
	 * @param platformFeeRate 平台服务费率
	 * @param unit 平均分配单位
	 * @return
	 */
	public static BigDecimal averagePlatformFee(BigDecimal repayTotalAmout, BigDecimal platformFeeRate, int unit){ 
		return repayTotalAmout.multiply(platformFeeRate).divide(new BigDecimal(unit), Constants.CURRENCY_CALCULATE_SCALE, BigDecimal.ROUND_HALF_UP);		
	}
	
	/**
	 * 提前还款手续费计算
	 *  提前还款手续费=合同金额*提前还款手续费率
	 * 
	 * @param contractAmout 合同金额
	 * @param rate 日费率 (默认为dayRate)
	 * @param rateType 利率类型
	 * @return
	 */
	public static BigDecimal repayEarlierFee(BigDecimal contractAmout, BigDecimal rate, String... rateType){
		BigDecimal dayRate = rate;
		if(rateType != null && rateType.length == 1){
			dayRate = rateConvert(rate, rateType[0]);
		}		
		return contractAmout.multiply(dayRate);			
	}
			
	/**
	 * 逾期管理服务费计算
	 * 逾期管理服务费=合同金额*日费率*逾期天数
	 * 
	 * 日利率 = 月利率/12
	 * 日利率 = 年利率/360
	 * @param contractAmout 合同金额
	 * @param rate 日费率 (默认为dayRate)
	 * @param overdueDays 逾期天数
	 * @param rateType 利率类型
	 * @return
	 */
	public static BigDecimal overduePlatformFee(BigDecimal contractAmout, BigDecimal rate, int overdueDays, String... rateType){
		BigDecimal dayRate = rate;
		if(rateType != null && rateType.length == 1){
			dayRate = rateConvert(rate, rateType[0]);
		}		
		return contractAmout.multiply(dayRate).multiply(new BigDecimal(overdueDays));			
	}
		
	/**
	 * 超期利息计算
	 * 超期利息=当期应还金额*日利率*逾期天数
	 * 
	 * @param repayAmout 当期应还金额 
	 * @param rate 日利率  (默认为dayRate)
	 * @param overdueDays 逾期天数
	 * @param rateType 利率类型
	 * @return
	 */
	public static BigDecimal overdueInterest(BigDecimal repayAmout, BigDecimal rate, int overdueDays, String... rateType){
		BigDecimal dayRate = rate;
		if(rateType != null && rateType.length == 1){
			dayRate = rateConvert(rate, rateType[0]);
		}		
		return repayAmout.multiply(dayRate).multiply(new BigDecimal(overdueDays));		
	}
	
	// 2）支付方：牛娃
	//逾期还款  资金垫付服务费=垫付费用*垫付天数*日费率
	
	// 基本 月利息'=待收本金*月利率
	
	/**
	 * 
	 * 利率转换
	 * TODO dict
	 * 
	 * 月利率 = 年利率/12
	 * 日利率 = 年利率/360
	 * 日利率 = 月利率/30
	 * @param rate
	 * @param rateType
	 * @return
	 */
	public static BigDecimal rateConvert(BigDecimal rate, String rateType){
		BigDecimal convertResult = rate;
		switch(rateType){
			case "YEART_TO_MONTH" : convertResult = rate.divide(Constants.MONTH_OF_YEAR, Constants.CURRENCY_CALCULATE_SCALE, BigDecimal.ROUND_HALF_UP);break;
			case "YEAR_TO_DAY" : convertResult = rate.divide(Constants.DAY_OF_YEAR, Constants.CURRENCY_CALCULATE_SCALE, BigDecimal.ROUND_HALF_UP);break;
			case "MONTH_TO_DAY" : convertResult = rate.divide(Constants.DAY_OF_MONTH, Constants.CURRENCY_CALCULATE_SCALE, BigDecimal.ROUND_HALF_UP);break;
		}
		return convertResult;
	}
	
}
